package com.wanjia.bpsapi.crontab;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.wanjia.bpsapi.mapper.PutClientMapper;
import com.wanjia.bpsapi.mapper.WjUserMapper;
import com.wanjia.bpsapi.pojo.dto.jkmc.UserVege;
import com.wanjia.bpsapi.pojo.entity.PutClient;
import com.wanjia.bpsapi.pojo.entity.WjUser;
import com.wanjia.bpsapi.service.jkmc.JkAsyncService;
import com.wanjia.bpsapi.service.jkmc.JkService;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.wanjia.bpsapi.constant.Constant.DAY2MILLIS;

@Service
@Slf4j
public class ProductFlushService {

    @Setter(onMethod_ = @Autowired)
    private PutClientMapper clientMapper;

    @Setter(onMethod_ = @Autowired)
    private WjUserMapper userMapper;

    @Setter(onMethod_ = @Autowired)
    private JkService jkService;

    @Setter(onMethod_ = @Autowired)
    private JkAsyncService asyncService;

    @Setter(onMethod_ = @Autowired)
    private TimedTaskBase timedTaskBase;

    @Setter(onMethod_ = @Autowired)
    private TimedTaskUser timedTaskUser;

    @Setter(onMethod_ = @Autowired)
    private TimedTaskVege timedTaskVege;

    @Setter(onMethod_ = @Autowired)
    private TimedTaskVegePrice timedTaskVegePrice;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private ProductFlushService thisService;

    public void flush() {
        List<PutClient> putClients = clientMapper.selectLatest();
        Map<Long, List<PutClient>> map = putClients.stream()
                .collect(Collectors.groupingBy(PutClient::getClientId));
        map.forEach((uid, list) -> {
            WjUser user = userMapper.selectById(uid);
            List<Long> productIds = collect(user, list);
            delete(uid, productIds);
        });
    }

    public void updateStock() {
        asyncService.updateStock();
    }

    private List<Long> collect(WjUser user, List<PutClient> list) {
        return list.stream()
                .filter(p -> !check(user, p))
                .map(PutClient::getVegeId)
                .collect(Collectors.toList());
    }

    private boolean check(WjUser user, PutClient p) {
        int quotationPeriod = Optional.of(user).map(WjUser::getQuotationPeriod).orElse(0);
        if (quotationPeriod < 0) {
            return true;
        }
        long current = new Date().getTime();
        long day = (current - p.getPutDate().getTime()) / DAY2MILLIS;
        if (day * DAY2MILLIS < current - p.getPutDate().getTime()) {
            day++;
        }

        return day < quotationPeriod;
    }

    private void delete(Long uid, List<Long> productIds) {
        if (uid == null || CollUtil.isEmpty(productIds)) {
            return;
        }
        List<UserVege> list = jkService.getList(uid);
        List<Long> deletes = list.stream()
                .map(UserVege::getProductId)
                .distinct()
                .filter(productIds::contains)
                .collect(Collectors.toList());
        if (CollUtil.isEmpty(deletes)) {
            return;
        }
        jkService.deleteUserVege(uid, ArrayUtil.toArray(deletes, Long.class));
        log.info("用户{}，下架商品{}", uid, deletes);
    }

    @Transactional(rollbackFor = Exception.class)
    public void async() {
        timedTaskBase.run();
        timedTaskUser.run();
        timedTaskVege.run();
        timedTaskVegePrice.run();
    }
}
